package com.ssy.lingxi.member.merchant.serviceimpl.web;

import com.ssy.lingxi.common.model.dto.UserLoginCacheDTO;
import com.ssy.lingxi.common.response.PageData;
import com.ssy.lingxi.common.response.ResponseCode;
import com.ssy.lingxi.common.response.Wrapper;
import com.ssy.lingxi.member.merchant.entity.MemberTradeCommentHistoryDO;
import com.ssy.lingxi.member.merchant.model.vo.comment.request.*;
import com.ssy.lingxi.member.merchant.model.vo.comment.response.MemberOrderTradeCommentPageVO;
import com.ssy.lingxi.member.merchant.model.vo.comment.response.MemberTradeCommentDetailVO;
import com.ssy.lingxi.member.merchant.model.vo.comment.response.PlatformMemberTradeCommentPageVO;
import com.ssy.lingxi.member.merchant.model.vo.maintenance.response.MemberDetailCreditCommentSummaryVO;
import com.ssy.lingxi.member.merchant.model.vo.maintenance.response.MemberDetailCreditTradeHistoryVO;
import com.ssy.lingxi.member.merchant.repository.MemberTradeCommentHistoryRepository;
import com.ssy.lingxi.member.merchant.service.base.IBaseMemberCacheService;
import com.ssy.lingxi.member.merchant.service.base.IBaseMemberDetailService;
import com.ssy.lingxi.member.merchant.service.web.IPlatformMemberCommentService;
import org.springframework.beans.BeanUtils;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.http.HttpHeaders;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import javax.persistence.criteria.Predicate;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 平台后台-评价管理服务接口实现类
 * @author 姚梓聪
 * @version 2.0.0
 * @date 2020-10-23
 */
@Service
public class PlatformMemberCommentServiceImpl implements IPlatformMemberCommentService {

    @Resource
    private IBaseMemberCacheService memberCacheService;

    @Resource
    private IBaseMemberDetailService baseMemberDetailService;

    @Resource
    private MemberTradeCommentHistoryRepository memberTradeCommentHistoryRepository;

    @Resource
    private JdbcTemplate jdbcTemplate;

    /**
     * 交易能力 - 评价管理 - 评价分页列表
     * @param headers Http头部信息
     * @param pageVO 接口参数
     * @return 查询结果
     */
    @Override
    public Wrapper<PageData<MemberOrderTradeCommentPageVO>> pageMemberOrderTradeCommentHistory(HttpHeaders headers, MemberOrderTradeCommentQueryVO pageVO) {
        memberCacheService.needLoginFromManagePlatform(headers);

        Pageable page = PageRequest.of(pageVO.getCurrent() - 1, pageVO.getPageSize(), Sort.by("createTime").descending());
        Specification<MemberTradeCommentHistoryDO> specification = (Specification<MemberTradeCommentHistoryDO>) (root, query, cb) -> {
            List<Predicate> predicateList = new ArrayList<>();
            if (!ObjectUtils.isEmpty(pageVO.getStar())) {
                predicateList.add(cb.equal(root.get("star"), pageVO.getStar()));
            }
            if (!ObjectUtils.isEmpty(pageVO.getComment())) {
                predicateList.add(cb.like(root.get("comment"), "%" + pageVO.getComment().trim() + "%"));
            }

            if (!ObjectUtils.isEmpty(pageVO.getDealTimeStart())) {
                predicateList.add(cb.greaterThanOrEqualTo(root.get("dealTime").as(LocalDateTime.class), pageVO.getDealTimeStart()));
            }
            if (!ObjectUtils.isEmpty(pageVO.getDealTimeEnd())) {
                predicateList.add(cb.lessThanOrEqualTo(root.get("dealTime").as(LocalDateTime.class), pageVO.getDealTimeEnd()));
            }
            if (!ObjectUtils.isEmpty(pageVO.getCreateTimeStart())) {
                predicateList.add(cb.greaterThanOrEqualTo(root.get("createTime").as(LocalDateTime.class), pageVO.getCreateTimeStart()));
            }
            if (!ObjectUtils.isEmpty(pageVO.getCreateTimeEnd())) {
                predicateList.add(cb.lessThanOrEqualTo(root.get("createTime").as(LocalDateTime.class), pageVO.getCreateTimeEnd()));
            }
            if (!ObjectUtils.isEmpty(pageVO.getMemberName())) {
                predicateList.add(cb.like(root.get("memberName"), "%" + pageVO.getMemberName().trim() + "%"));
            }
            if (!ObjectUtils.isEmpty(pageVO.getSubMemberName())) {
                predicateList.add(cb.like(root.get("subMemberName"), "%" + pageVO.getSubMemberName().trim() + "%"));
            }
            if (!ObjectUtils.isEmpty(pageVO.getProduct())) {
                predicateList.add(cb.like(root.get("product"), "%" + pageVO.getProduct() + "%"));
            }

            Predicate[] p = new Predicate[predicateList.size()];
            return cb.and(predicateList.toArray(p));
        };


        Page<MemberTradeCommentHistoryDO> pageList = memberTradeCommentHistoryRepository.findAll(specification, page);

        List<MemberOrderTradeCommentPageVO> resultList = pageList.stream().map(e -> {
            MemberOrderTradeCommentPageVO commentPageVO = new MemberOrderTradeCommentPageVO();
            BeanUtils.copyProperties(e, commentPageVO);
            commentPageVO.setOrderNo(e.getOrderNo());
            return commentPageVO;
        }).collect(Collectors.toList());

        return Wrapper.success(new PageData<>(pageList.getTotalElements(), resultList));
    }

    /**
     * 交易能力 - 评价管理 - 评价详情
     * @param headers Http头部信息
     * @param tradeCommentIdVO 接口参数
     * @return 查询结果
     */
    @Override
    public Wrapper<MemberTradeCommentDetailVO> getMemberTradeCommentHistory(HttpHeaders headers, MemberTradeCommentIdVO tradeCommentIdVO) {
        memberCacheService.needLoginFromManagePlatform(headers);
        MemberTradeCommentHistoryDO commentHistoryDO = memberTradeCommentHistoryRepository.findById(tradeCommentIdVO.getId()).orElse(null);
        if (ObjectUtils.isEmpty(commentHistoryDO)) {
            return Wrapper.fail(ResponseCode.MC_MS_COMMENT_NOT_FOUND);
        }

        // 返回
        MemberTradeCommentDetailVO commentPageVO = new MemberTradeCommentDetailVO();
        commentPageVO.setId(commentHistoryDO.getId());
        commentPageVO.setMemberName(commentHistoryDO.getMemberName());
        commentPageVO.setStar(commentHistoryDO.getStar());
        commentPageVO.setComment(commentHistoryDO.getComment());
        commentPageVO.setProduct(commentHistoryDO.getProduct());
        commentPageVO.setOrderNo(commentHistoryDO.getOrderNo());
        commentPageVO.setDealTime(commentHistoryDO.getDealTime());
        commentPageVO.setPrice(commentHistoryDO.getPrice());
        commentPageVO.setTotalPrice(commentHistoryDO.getTotalPrice());
        commentPageVO.setPics(commentHistoryDO.getPics());
        commentPageVO.setProductImgUrl(commentHistoryDO.getProductImgUrl());
        commentPageVO.setPurchaseCount(commentHistoryDO.getDealCount());
        commentPageVO.setUnit(commentHistoryDO.getUnit());

        return Wrapper.success(commentPageVO);
    }

    /**
     * 平台后台 - 评价管理 - 会员评价查询分页列表
     * @param headers Http头部信息
     * @param pageVO 接口参数
     * @return 查询结果
     */
    @Override
    public Wrapper<PageData<PlatformMemberTradeCommentPageVO>> pagePlatformMemberTradeComment(HttpHeaders headers, PlatformMemberTradeCommentQueryVO pageVO) {
        UserLoginCacheDTO loginUser = memberCacheService.needLoginFromManagePlatform(headers);

        //构建With语句，头和尾部
        String countFormat = "with tmp as (%s) select count(*) from tmp";

        //构建Native查询语句
        StringBuilder joinTableBuilder = new StringBuilder();
        joinTableBuilder.append("select mmmtch.sub_member_id as memberId , mmm.name as memberName , mmmtch.sub_role_id as roleId, mmr.role_name as roleName, mmmt.type_enum as memberType, mmmt.type_name as memberTypeName, mmmlr.level_tag as levelTag, round(avg(mmmtch.star)) as avgStar, count(*) as receiveCountTotal, sum(case when date_part('day',  localtimestamp - mmmtch.create_time) <= 7 then 1 else 0 end) as receiveCount7, sum(case when date_part('day',  localtimestamp - mmmtch.create_time) <= 180 then 1 else 0 end) as receiveCount180  from ms_mc_member_trade_comment_history mmmtch \n" +
                "left outer join ms_mc_member mmm on mmmtch.sub_member_id = mmm.id \n" +
                "left outer join ms_mc_role mmr on mmmtch.sub_role_id = mmr.id \n" +
                "left outer join ms_mc_member_type mmmt on mmr.member_type_id = mmmt.id \n" +
                "left outer join ms_mc_member_level_right mmmlr on mmmtch.sub_member_id = mmmlr.sub_member_id and mmmtch.sub_role_id = mmmlr.sub_role_id \n");

        StringBuilder whereBuilder = new StringBuilder();
        whereBuilder.append(String.format("where mmmlr.member_id = %d and mmmlr.role_id = %d ", loginUser.getMemberId(), loginUser.getMemberRoleId()));

        String groupByStr = " group by mmmtch.sub_member_id , mmm.name, mmmtch.sub_role_id, mmr.role_name, mmmt.type_enum, mmmt.type_name, mmmlr.level_tag ";

        String orderByStr = " order by mmmtch.sub_member_id , mmmtch.sub_member_id ";

        String limitStr = String.format(" limit %d offset %d", pageVO.getPageSize(), (pageVO.getCurrent() -1) * pageVO.getPageSize());

        StringBuilder havingBuilder = new StringBuilder();
        if(pageVO.getAvgStar() != null && !pageVO.getAvgStar().equals(0)) {
            havingBuilder.append(" having round(avg(mmmtch.star)) = ").append(pageVO.getAvgStar()).append(" ");
        }

        if (pageVO.getMemberTypeId() != null && !pageVO.getMemberTypeId().equals(0L)) {
            whereBuilder.append(" and mmmt.id = ").append(pageVO.getMemberTypeId());
        }

        if(pageVO.getRoleId() != null && !pageVO.getRoleId().equals(0L)) {
            whereBuilder.append(" and mmmtch.sub_role_id = ").append(pageVO.getRoleId());
        }

        if(pageVO.getLevel() != null && !pageVO.getLevel().equals(0)) {
            whereBuilder.append(" and mmmlr.level = ").append(pageVO.getLevel());
        }

        if(StringUtils.hasLength(pageVO.getMemberName())) {
            whereBuilder.append(" and mmm.name like '%").append(pageVO.getMemberName().trim()).append("%'");
        }

        String nativeSqlStr = joinTableBuilder.append(whereBuilder).append(groupByStr).append(havingBuilder).append(orderByStr).toString();
        String nativeCountStr = String.format(countFormat, nativeSqlStr);

        //拼接完 count 语句后，才拼接分页查询条件
        nativeSqlStr += limitStr;

        System.out.println(nativeCountStr);
        System.out.println(nativeSqlStr);

        Long totalCount = jdbcTemplate.queryForObject(nativeCountStr, Long.class);
        if(totalCount == null) {
            totalCount = 0L;
        }

        List<PlatformMemberTradeCommentPageVO> resultList = new ArrayList<>();
        if(totalCount > 0) {
            resultList = jdbcTemplate.query(nativeSqlStr, new BeanPropertyRowMapper<>(PlatformMemberTradeCommentPageVO.class));
        }

        return Wrapper.success(new PageData<>(totalCount, resultList));
    }

    @Override
    public Wrapper<Void> deletePlatformMemberTradeComment(HttpHeaders headers, MemberTradeCommentIdsVO tradeCommentIdsVO) {
        memberCacheService.needLoginFromManagePlatform(headers);

        List<Long> ids = tradeCommentIdsVO.getIds();
        memberTradeCommentHistoryRepository.deleteAllByIdIn(ids);
        return Wrapper.success();
    }

    @Override
    public Wrapper<Void> updateStatusPlatformMemberTradeComment(HttpHeaders headers, MemberTradeCommentUpdateStatusVO updateStatusVO) {
        memberCacheService.needLoginFromManagePlatform(headers);

        MemberTradeCommentHistoryDO memberTradeCommentHistoryDO = memberTradeCommentHistoryRepository.findById(updateStatusVO.getId()).orElse(null);
        if (ObjectUtils.isEmpty(memberTradeCommentHistoryDO)) {
            return Wrapper.fail(ResponseCode.MC_MS_COMMENT_NOT_FOUND);
        }

        memberTradeCommentHistoryDO.setStatus(updateStatusVO.getStatus());
        memberTradeCommentHistoryRepository.saveAndFlush(memberTradeCommentHistoryDO);

        return Wrapper.success();
    }

    /**
     * 会员详情 - 会员信用 - 交易评价汇总（平台层面汇总）
     * @param headers Http头部信息
     * @param pageVO 接口参数
     * @return 查询结果
     */
    @Override
    public Wrapper<MemberDetailCreditCommentSummaryVO> getAllMemberDetailCreditTradeCommentSummary(HttpHeaders headers, PlatformMemberTradeCommentSummaryVO pageVO) {
        memberCacheService.needLoginFromManagePlatform(headers);
        return baseMemberDetailService.getAllMemberDetailCreditTradeCommentSummary(pageVO.getMemberId(), pageVO.getRoleId());
    }

    /**
     * 平台后台-评价管理-分页查询交易评论历史记录
     *
     * @param headers Http头部信息
     * @param pageVO  接口参数
     * @return 查询结果
     */
    @Override
    public Wrapper<PageData<MemberDetailCreditTradeHistoryVO>> pagePlatformMemberTradeCommentHistory(HttpHeaders headers, PlatformMemberTradeCommentHistoryVO pageVO) {
        memberCacheService.needLoginFromManagePlatform(headers);
        return baseMemberDetailService.pageAllMemberDetailCreditTradeCommentHistory(pageVO.getMemberId(), pageVO.getRoleId(), pageVO.getStarLevel(), pageVO.getCurrent(), pageVO.getPageSize());
    }
}
